<?php
/**
 * #Celebrate Shieh
 *             ,%%%%%%%%,
 *           ,%%/\%%%%/\%%
 *          ,%%%\c "" J/%%%
 * %.       %%%%/ o  o \%%%
 * `%%.     %%%%    _  |%%%
 *  `%%     `%%%%(__Y__)%%'
 *  //       ;%%%%`\-/%%%'
 * ((       /  `%%%%%%%'
 *  \\    .'          |
 *   \\  /       \  | |
 *    \\/         ) | |
 *     \         /_ | |__
 *     (___________))))))) 攻城湿
 *
 *        _       _
 * __   _(_)_   _(_) __ _ _ __
 * \ \ / / \ \ / / |/ _` |'_ \
 *  \ V /| |\ V /| | (_| | | | |
 *   \_/ |_| \_/ |_|\__,_|_| |_|
 */

use App\Libs\Storage\StorageFile;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Models\Mongo\Admin;
use App\Models\Mongo\Blog;
use Illuminate\Support\Facades\Mail;
use Jenssegers\Agent\Agent;

if ( ! function_exists('GetRandStr') ) {
    /**
     * 获取随机数
     *
     * @param int $len
     *
     * @return string
     */
    function GetRandStr( int $len = 6 )
    {
        $chars    = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" ];//这里支取数字
        $charsLen = count($chars) - 1;
        shuffle($chars);
        $output = "";
        for ( $i = 0; $i < $len; $i++ ) $output .= $chars[ mt_rand(0, $charsLen) ];
        return $output;
    }
}

if ( ! function_exists('GetRandCode') ) {
    /**
     * 生成邀请码
     *
     * @param $length
     *
     * @return string
     */
    function GetRandCode( $length )
    {
        $sourceString = [
            'A', 'B', 'C', 'D', 'E', 'F',
            'G', 'H', 'I', 'J', 'K', 'L',
            'M', 'N', 'O', 'P', 'Q', 'R',
            'S', 'T', 'U', 'V', 'W', 'X',
            'Y', 'Z',
        ];

        $code = '';
        for ( $i = 0; $i < $length; $i++ ) $code .= $sourceString[ mt_rand(0, 25) ];    //生成php随机数
        return $code;
    }
}

if ( ! function_exists('data') ) {
    /**
     * 返回数据格式化
     *
     * @param null   $data
     * @param string $msg
     * @param int    $code
     *
     * @return \Illuminate\Http\JsonResponse
     */
    function data( $data = NULL, $msg = 'success', $code = 200 )
    {
        return response()->json([
            'data' => $data,
            'code' => $code,
            'msg'  => $msg,
        ]);
    }
}


if ( ! function_exists('message') ) {
    /**
     * 返回数据格式化
     *
     * @param string $msg
     * @param int    $code
     *
     * @return \Illuminate\Http\JsonResponse
     */
    function message( $msg = 'error', $code = 505 )
    {
        return response()->json([
            'data' => NULL,
            'code' => $code,
            'msg'  => $msg,
        ]);
    }
}

if ( ! function_exists('maxsize') ) {
    /**
     * 计算大小和保留几位小数
     *
     * @param int $size 大小
     * @param int $pre  保留位数
     *
     * @return string
     */
    function maxsize( int $size, int $pre = 2 )
    {
        $rank = 0;
        while ( $size > 1024 ) {
            $size = $size / 1024;
            $rank++;
        }
        $size = round($size, $pre);
        switch ( $rank ) {
            case "1":
                $unit = "KB";
                break;
            case "2":
                $unit = "MB";
                break;
            case "3":
                $unit = "GB";
                break;
            case "4":
                $unit = "TB";
                break;
            case "5":
                $unit = "PB";
                break;
            case "6":
                $unit = "EB";
                break;
            case "7":
                $unit = "ZB";
                break;
            case "8":
                $unit = "YB";
                break;
            default :
                $unit = "Bytes";
                break;
        }
        return $size . " " . $unit;
    }
}


if ( ! function_exists('errorStorage') ) {
    /**
     * 写入日志
     *
     * @param string $name  文件夹名称
     * @param null   $data  错误内容
     * @param string $title 错误标题
     * @param string $info  文件名称
     * @param string $exp   标题
     */
    function errorStorage( string $name = 'error', $data = NULL, string $title = 'error', string $info = 'error', string $exp = '' )
    {
        $success = '';
        $disk    = new StorageFile('storage');//Storage 文件系统
        if ( is_array($data) ) foreach ( $data as $key => $value ) $success .= $key . '=>' . $value . ' ';
        else $success = $data;
        $content = '[' . Carbon::now() . '] ' . ' [' . $exp . '] ' . $title . ' : ' . $info . ' { ' . $success . ' } ';//内容格式
        $name    = 'logs/' . $name . '/' . $name . '-' . $info . '-' . Carbon::now()->toDateString() . '.log';//文件名
        $del     = $disk->exists($name);//获取文件是否存在
        if ( $del ) $disk->append($name, $content);//存在就写入
        else $disk->put($name, $content);//创建并写入
    }
}

if ( ! function_exists('size') ) {
    /**
     * 根据类型和大小计算 值
     *
     * @param int $cate 类型
     * @param int $size 值
     *
     * @return float|int
     */
    function size( int $cate = 0, int $size = 0 )
    {
        $unit = 0;
        if ( $cate === 1 ) $size = 1024 * $size;//1为KB
        else if ( $cate ) {//否则 $cate 为0得情况就是 bytes 填的多少就是多少
            for ( $i = 1; $i < $cate; $i++ ) {
                if ( $unit !== 0 ) $unit *= 1024;
                else $unit = 1024 * 1024;
            }
            $size = $unit * $size;
        }
        return $size;
    }
}


if ( ! function_exists('filter') ) {
    /**
     * 过滤得字段
     *
     * @param string $str
     *
     * @return mixed|string
     */
    function filter( string $str )
    {
        $str = str_replace('*', '', $str);
        $str = str_replace('%', '', $str);
        $str = str_replace('$', '', $str);
        $str = str_replace('"', '', $str);
        $str = str_replace('\'', '', $str);
        $str = str_replace('=', '', $str);
        $str = str_replace('?', '', $str);
        $str = str_replace('`', '', $str);
        $str = str_replace('!', '', $str);
        $str = str_replace('^', '', $str);
        $str = str_replace('  ', '', $str);
        $str = str_replace('_', '', $str);
        $str = str_replace('|', '', $str);
        $str = str_replace('[', '', $str);
        $str = str_replace(']', '', $str);
        $str = str_replace('{', '', $str);
        $str = str_replace('}', '', $str);
        $str = str_replace('<', '', $str);
        $str = str_replace('>', '', $str);
        return $str;
    }
}


if ( ! function_exists('assetImage') ) {
    /**
     * 自动获取图片
     *
     * @param string $url
     *
     * @return string
     */
    function assetImage( string $url )
    {
        $name = strtolower(pathinfo($url, PATHINFO_EXTENSION));//获取后缀名
        if ( ! $name ) return asset('static/preview/other.png');//后缀不存在就返回默认图片
        $path = [ 'jpg', 'jpeg', 'png', 'gif' ];
        $disk = new StorageFile();
        if ( ! $disk->exists($url) && in_array($name, $path) ) return asset($url);//判断 后缀是否是图片类型
        $file = [];
        foreach ( scandir(public_path() . '/static/preview') as $value ) $file[] = strtolower(pathinfo($value, PATHINFO_FILENAME)); //扫描文件夹下所以文件存入$file数组
        if ( in_array($name, $file) ) return asset('static/preview/' . $name . '.png');//图片存在直接返回图片，不存在就返回默认图
        return asset('static/preview/other.png');
    }
}


if ( ! function_exists('isMobile') ) {
    /**
     * 判断是否是手机
     *
     * @return string
     */
    function isMobile()
    {
        // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
        if ( isset ($_SERVER[ 'HTTP_X_WAP_PROFILE' ]) ) return '移动设备';
        // 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
        if ( isset ($_SERVER[ 'HTTP_VIA' ]) ) return stristr($_SERVER[ 'HTTP_VIA' ], "wap") ? '移动设备' : 'pc';// 找不到为flase,否则为TRUE
        // 判断手机发送的客户端标志,兼容性有待提高
        if ( isset ($_SERVER[ 'HTTP_USER_AGENT' ]) ) {
            $clientKeyWords = [
                'mobile',
                'nokia',
                'sony',
                'ericsson',
                'mot',
                'samsung',
                'htc',
                'sgh',
                'lg',
                'sharp',
                'sie-',
                'philips',
                'panasonic',
                'alcatel',
                'lenovo',
                'iphone',
                'ipod',
                'blackberry',
                'meizu',
                'android',
                'netfront',
                'symbian',
                'ucweb',
                'windowsce',
                'palm',
                'operamini',
                'operamobi',
                'openwave',
                'nexusone',
                'cldc',
                'midp',
                'wap',
            ];
            if ( preg_match("/(" . implode('|', $clientKeyWords) . ")/i", strtolower($_SERVER[ 'HTTP_USER_AGENT' ])) ) return '移动设备';
        }
        if ( isset ($_SERVER[ 'HTTP_ACCEPT' ]) ) if ( ( strpos($_SERVER[ 'HTTP_ACCEPT' ], 'vnd.wap.wml') !== FALSE ) && ( strpos($_SERVER[ 'HTTP_ACCEPT' ], 'text/html') === FALSE || ( strpos($_SERVER[ 'HTTP_ACCEPT' ], 'vnd.wap.wml') < strpos($_SERVER[ 'HTTP_ACCEPT' ], 'text/html') ) ) ) return '移动设备';
        return 'pc';
    }
}


if ( ! function_exists('logMongo') ) {
    /**
     * 写入mongodb
     *
     * @param string $name
     *
     * @return bool
     */
    function logMongo( string $name = 'admin' )
    {
        $data                       = [];
        $agent                      = new Agent();
        $request                    = Request::capture();
        $data[ 'ip' ]               = $request->ip();//获取当前IP；
        $data[ 'type' ]             = $request->format();//资源类型
        $data[ 'method' ]           = $request->method();//请求方法
        $data[ 'isAjax' ]           = var_export($request->ajax(), TRUE);//是否ajax请求
        $data[ 'module' ]           = $request->getRequestUri();//当前模块名称
        $data[ 'url' ]              = $request->url();//获取当前URL地址
        $data[ 'browser' ]          = $agent->browser();//获取当前浏览器
        $data[ 'browser_version' ]  = $agent->version($data[ 'browser' ]);//获取当前浏览器版本
        $data[ 'platform' ]         = $agent->platform();//获取当前操作系统
        $data[ 'platform_version' ] = $agent->version($data[ 'platform' ]);//获取当前操作系统版本
        $data[ 'lang' ]             = implode(',', $agent->languages());//获取语言
        $data[ 'os' ]               = $agent->device();//获取系统
        $data[ 'mobile' ]           = isMobile();//获取类型
        switch ( $name ) {//存入mongodb
            case 'admin':
                Admin::CreateModel($data);
                break;
            case 'blog':
                Blog::CreateModel($data);
                break;
            default:
                return TRUE;
                break;
        }
    }
}

if ( ! function_exists('sub') ) {

    /**
     * 截取, 并加上...
     *
     * @param      $string
     * @param int  $size
     * @param bool $dot 是否加上..., 默认true
     *
     * @return bool|string
     */
    function sub( $string, int $size = 10, bool $dot = TRUE )
    {
        $string = strip_tags(trim($string));//去除字符串中的 HTML 标签
        if ( mb_strlen($string) > $size ) {//strlen获取字符串长度mb中文
            $string = mb_substr($string, 0, $size);//截取包括中文字符
            $string .= $dot ? '...' : '';//拼接
        }
        return $string;
    }
}

if ( ! function_exists('formatNum') ) {
    /**
     * 每三位数加，
     *
     * @param string $str
     *
     * @return string
     */
    function formatNum( string $str )
    {
        if ( substr($str, 0, 1) == '-' ) {
            $str  = str_replace('-', '', $str);//去除负数
            $name = TRUE;//为真是负数
        }
        else $name = FALSE;//为假是整数
        $newStr = '';
        $count  = 0;
        for ( $i = strlen($str) - 1; $i >= 0; $i-- ) {
            if ( $count % 3 == 0 && $count != 0 ) $newStr = $str[ $i ] . ',' . $newStr;//循环计算出每三位加，
            else $newStr = $str[ $i ] . $newStr;//否则拼接
            $count++;
        }
        if ( $name ) return '-' . $newStr;//加上负数
        else return $newStr;
    }
}

if ( ! function_exists('calculationNum') ) {
    /**
     * 计算
     *
     * @param string $n1
     * @param string $n2
     * @param        $status
     * @param int    $scale
     *
     * @return string|null
     */
    function calculationNum( string $n1, string $n2, $status, $scale = 0 )
    {
        try {
            switch ( $status ) {
                case '+':
                    return bcadd($n1, $n2, $scale);//精准加法
                    break;
                case '-':
                    return bcsub($n1, $n2, $scale);//精准减法
                    break;
                case '×':
                    return bcmul($n1, $n2, $scale);//精准乘法
                    break;
                case '÷':
                    return bcdiv($n1, $n2, $scale);//精准除法
                    break;
                default:
                    return '';
                    break;
            }
        } catch ( \Exception $exception ) {
            return '';
        }
    }
}

if ( ! function_exists('trimAll') ) {
    /**
     * 去除换行和空格
     *
     * @param string $str
     *
     * @return mixed
     */
    function trimAll( string $str )
    {
        $trimAll = [ " ", "　", "\t", "\n", "\r" ];//各种空格 换行格式
        return str_replace($trimAll, '', $str);//去除
    }
}

if ( ! file_exists('ExcelFile') ) {
    /**
     * 转为 Excel
     *
     * @param string $fileName
     * @param array  $xlsData
     *
     * @return bool
     */
    function ExcelFile( string $fileName, array $xlsData )
    {
        try {
            require_once( base_path('app/Libs/PHPExcel/PHPExcel/Worksheet/Drawing.php') );
            require_once( base_path('app/Libs/PHPExcel/PHPExcel/Writer/Excel2007.php') );
            $objExcel = new PHPExcel();//实例化插件
            //set document Property
            $objActSheet = $objExcel->getActiveSheet();
            $letter      = explode(',', "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,
        AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR,AS,AT,AU,AV,AW,AX,AY,AZ");//表格
            $i           = 2;
            foreach ( $xlsData as $n => $v ) {
                $k = 0;
                foreach ( $v as $key => $value ) {
                    $objActSheet->setCellValue($letter[ $k ] . '1', $key);  //填充表头信息
                    $objActSheet->setCellValue($letter[ $k ] . $i, $value); //填充表格信息
                    $k++;
                }
                $i++;
            }
            $objWriter = \PHPExcel_IOFactory::createWriter($objExcel, 'Excel2007');//添加
            $objWriter->save($fileName);//写入
            unset($objWriter);//销毁变量
            unset($objActSheet);//销毁变量
            return TRUE;
        } catch ( \Exception $exception ) {
            return FALSE;
        }
    }
}

if ( ! file_exists('TextFile') ) {
    /**
     * 写入文件到txt
     *
     * @param string $myFile
     * @param array  $caking
     *
     * @return bool
     */
    function TextFile( string $myFile, array $caking )
    {
        try {
            $name = fopen($myFile, "w");//打开文件，没有就创建
            foreach ( $caking as $log ) {
                foreach ( $log as $key => $value ) {
                    $text = '';
                    $text .= " $key = $value";//拼接
                    $txt  = "$text";
                    fwrite($name, $txt);//写入
                }
                $txt = "\r\n";//换行
                fwrite($name, $txt);//写入
            }
            fclose($name);//关闭文件
            return TRUE;
        } catch ( \Exception $exception ) {
            return FALSE;
        }
    }
}


if ( ! function_exists('getFileType') ) {
    /**
     * 根据类型来判断后缀名
     *
     * @param string $val
     *
     * @return string
     */
    function getFileType( string $val )
    {
        switch ( strtolower($val) ) {
            case 'vnd.openxmlformats-officedocument.wordprocessingml.document':
                return 'docx';
                break;
            case 'msword':
                return 'doc';
                break;
            case 'openxmlformats-officedocument.wordprocessingml.template':
                return 'dotx';
                break;
            case 'vnd.ms-word.document.macroenabled.12':
                return 'docm';
                break;
            case 'vnd.ms-word.template.macroenabled.12':
                return 'dotm';
                break;
            case 'vnd.ms-excel':
                return 'xls';
                break;
            case 'vnd.openxmlformats-officedocument.spreadsheetml.sheet':
                return 'xlsx';
                break;
            case 'vnd.openxmlformats-officedocument.spreadsheetml.template':
                return 'xltx';
                break;
            case 'vnd.ms-excel.sheet.macroenabled.12':
                return 'xlsm';
                break;
            case 'vnd.ms-excel.template.macroenabled.12':
                return 'xltm';
                break;
            case 'vnd.ms-excel.addin.macroenabled.12':
                return 'xlam';
                break;
            case 'vnd.ms-excel.sheet.binary.macroenabled.12':
                return 'xlsb';
                break;
            case 'vnd.ms-powerpoint':
                return 'ppt';
                break;
            case 'vnd.openxmlformats-officedocument.presentationml.presentation':
                return 'pptx';
                break;
            case 'vnd.openxmlformats-officedocument.presentationml.template':
                return 'potx';
                break;
            case 'vnd.openxmlformats-officedocument.presentationml.slideshow':
                return 'ppsx';
                break;
            case 'x-msdownload':
                return 'exe';
                break;
            case 'x-bmp':
                return 'bmp';
                break;
            case 'x-dwg':
                return 'dwg';
                break;
            case 'gif':
                return 'gif';
                break;
            case 'jpeg':
                return 'jpg';
                break;
            case 'html':
                return 'html';
                break;
            case 'mpeg4':
                return 'mp4';
                break;
            case 'x-ppt':
                return 'ppt';
                break;
            case 'vnd.rn-realmedia':
                return 'rm';
                break;
            case 'vnd.rn-realsystem-rjs':
                return 'rjs';
                break;
            case 'x-shockwave-flash':
                return 'swf';
                break;
            case 'vnd.rn-realmedia-vbr':
                return 'rmvb';
                break;
            case 'vnd.rn-rn_music_package':
                return 'rmp';
                break;
            case 'x-pn-realaudio-plugin':
                return 'rpm';
                break;
            case 'png':
                return 'png';
                break;
            case 'pdf':
                return 'pdf';
                break;
            case 'mp3':
                return 'mp3';
                break;
            case 'mp2':
                return 'mp2';
                break;
            case 'htm':
                return 'htm';
                break;
            case 'x-dwf':
                return 'dwf';
                break;
            case 'avi':
                return 'avi';
                break;
            case 'postscript':
                return 'ai';
                break;
            case 'xml':
                return 'biz';
                break;
            case 'zip':
                return 'zip';
                break;
            case 'mp4':
                return 'mp4';
                break;
            case 'rfc822_missing_envelope':
                return 'eml';
                break;
            default:
                return 'txt';
                break;
        }
    }
}

if ( ! function_exists('secToTime') ) {
    /**
     * 秒转时分
     *
     * @param string $time
     * @param string $status
     *
     * @return bool|string
     */
    function secToTime( string $time, string $status = 'i' )
    {
        try {
            $day    = floor($time / 3600 / 24);    //倒计时还有多少天
            $hour   = floor($time / 3600 % 24);     //倒计时还有多少小时（%取余数）
            $minute = floor($time / 60 % 60);      //倒计时还有多少分钟
            $second = floor($time % 60);         //倒计时还有多少秒
            switch ( $status ) {
                case 's':
                    $result = $second . '秒';
                    break;
                case 'i':
                    $result = $minute . '分';
                    break;
                case 'h':
                    $result = $hour . '时' . $minute . '分';
                    break;
                case 'd':
                    $result = $day . '天' . $hour . '时' . $minute . '分';
                    break;
                default:
                    throw new \Exception('参数错误');
                    break;
            }
            return $result;
        } catch ( \Exception $exception ) {
            return FALSE;
        }
    }
}

if ( ! function_exists('emailMail') ) {
    /**
     * 发送邮件
     *
     * @param $data
     *
     * @return bool
     */
    function emailMail( $data )
    {
        if ( ! $data[ 'id' ] ) Mail::raw($data[ 'content' ], function ( $message ) use ( $data ) {
            $message->to($data[ 'email' ])->subject($data[ 'name' ]);//普通邮件
        });
        else  Mail::send('vendor.index', [ 'name' => $data[ 'content' ] ], function ( $message ) use ( $data ) {//模板邮件
            $message->to($data[ 'email' ])->subject($data[ 'name' ]);
            if ( ! empty($data[ 'file' ]) ) foreach ( $data[ 'file' ] as $value ) {//存在附件 循环加密发送
                $name = explode('.', $value[ 'name' ]);
                $message->attach($value[ 'url' ], [ 'as' => '=?UTF-8?B?"' . base64_encode(reset($name)) . '?=.' . end($name) . '' ]);//加密
            }
        });
        if ( count(Mail::failures()) > 1 ) return FALSE;
        return TRUE;
    }
}
